package com.gitee.feizns.dynamic;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Supplier;

/**
 * Set工具类
 * @author feizns
 * @since 2024/12/2
 */
public abstract class Sets {

    /**
     * 简单集合
     * @param ts 茨
     * @return {@link Set }<{@link T }>
     */
    @SafeVarargs
    public static <T> Set<T> of(T[]... ts) {
        return of(LinkedHashSet::new, ts);
    }

    /**
     * 简单集合
     * @param ts 茨
     * @return {@link Set }<{@link T }>
     */
    @SafeVarargs
    public static <T> Set<T> of(Iterable<T>... iterables) {
        return of(LinkedHashSet::new, iterables);
    }

    /**
     * 简单集合
     * @param ts 茨
     * @return {@link Set }<{@link T }>
     */
    @SafeVarargs
    public static <T> Set<T> of(Iterator<T>... iterators) {
        return of(LinkedHashSet::new, iterators);
    }

    /**
     * Set
     * @param setSupplier SetSupplier
     * @param ts 数据
     * @return {@link Set }<{@link T }>
     */
    @SafeVarargs
    public static <T> Set<T> of(Supplier<Set<T>> setSupplier, T[]... ts) {
        Set<T> set = setSupplier.get();
        for (T[] t : ts)
            set.addAll(Arrays.asList(t));
        return set;
    }

    /**
     * Set
     * @param setSupplier SetSupplier
     * @param iterables 可迭代对象
     * @return {@link Set}<{@link T}>
     */
    @SafeVarargs
    public static <T> Set<T> of(Supplier<Set<T>> setSupplier, Iterable<T>... iterables) {
        Set<T> set = setSupplier.get();
        for (Iterable<T> iterable : iterables)
            for (T t : iterable)
                set.add(t);
        return set;
    }

    /**
     * Set
     * @param setSupplier SetSupplier
     * @param iterators 迭代器
     * @return {@link Set}<{@link T}>
     */
    @SafeVarargs
    public static <T> Set<T> of(Supplier<Set<T>> setSupplier, Iterator<T>... iterators) {
        Set<T> set = setSupplier.get();
        for (Iterator<T> iterator : iterators) {
            while (iterator.hasNext())
                set.add(iterator.next());
        }
        return set;
    }

}
